<template>
    <div v-if="!state.isAuthorized" class="white-box">
        <cellTip showMore :datas="['暂未授权微信小程序，请先授权小程序']" />
        <el-button
            v-hasPermi="['enttp:program:authorization']"
            type="primary"
            link
            @click="openIframe"
        >
            去授权
        </el-button>
    </div>

    <div v-else class="white-box">
        <cellTip
            showMore
            :datas="[
                '注意',
                '提交步骤：请先提交代码，然后再提交审核，待审核通过后点击“发布”按钮进行发布，最后点击发布即可上线小程序。',
                '更新记录：查看之前提交的版本信息',
                '回退版本：除非最新的线上版本有问题时，可选择回退版本，否则建议不要回退版本（可能会影响小程序部分功能）',
                '更新信息：点击更新信息后会获取最新的小程序信息',
                '提交代码成功后会生成体验版，此时可点击查看体验版进行扫码体验（建议首次查看体验版请先提交审核及发布小程序）',
            ]"
        />

        <!-- 版本信息 -->
        <PubTitle class="mt-14 mb-6" title="版本信息" />
        <div class="info-item">
            <div class="left">线上版本：</div>
            <div class="right">
                <span>{{ versionInfo && versionInfo.exp_version }}</span>
                <div class="btns">
                    <el-popover placement="left" :width="200" trigger="click">
                        <template #reference
                            ><el-button
                                v-hasPermi="['enttp:program:getTrialQRCode']"
                                type="primary"
                                link
                                @click="getCode"
                            >
                                查看体验版
                            </el-button></template
                        >
                        <img v-if="qrCode" :src="qrCode" class="w-175 h-175" />
                    </el-popover>

                    <el-button
                        v-hasPermi="['enttp:program:getRevertCodeRelease']"
                        type="primary"
                        link
                        @click="onClickBackVersion"
                    >
                        版本回退
                    </el-button>
                    <el-button
                        v-hasPermi="['enttp:program:getVersionCommit']"
                        type="primary"
                        link
                        @click="onClickUpdateRecord"
                    >
                        更新记录
                    </el-button>
                </div>
            </div>
        </div>
        <div class="info-item">
            <div class="left">更新时间：</div>
            <div class="right">{{ versionInfo && versionInfo.exp_desc }}</div>
        </div>
        <div class="info-item">
            <div class="left">审核状态：</div>
            <div class="right">
                <div class="flex items-center">
                    <span>
                        {{
                            reviewStatusInfo.commitType === 0
                                ? "上传代码成功,等待提交审核"
                                : dictStore.getDictMemberName(
                                      "mini_program_commit_status",
                                      reviewStatusInfo.commitStatus
                                  )
                        }}
                    </span>
                    <el-tooltip
                        v-if="reviewStatusInfo.commitStatus === 1"
                        effect="dark"
                        :content="reviewStatusInfo.reason"
                        raw-content
                        placement="top"
                        popper-class="max-w-400"
                    >
                        <el-icon class="ml-5"><WarningFilled /></el-icon>
                    </el-tooltip>
                </div>

                <div class="btns">
                    <el-button
                        v-hasPermi="['enttp:program:commit']"
                        type="primary"
                        link
                        :loading="commitLoading"
                        @click="commit"
                    >
                        提交代码
                    </el-button>
                    <!-- 最新的提交记录为提交代码时，并且状态为【审核被拒绝】、【已撤回】才显示审核按钮 -->
                    <el-button
                        v-hasPermi="['enttp:program:submitAudit']"
                        v-if="reviewStatusInfo.commitType === 0"
                        type="primary"
                        link
                        :loading="reviewLoading"
                        @click="review"
                    >
                        提交审核
                    </el-button>
                    <!-- 最新的提交记录为提交审核时，并且状态为【审核中】才显示撤回按钮 -->
                    <el-button
                        v-hasPermi="['enttp:program:undoCodeAudit']"
                        v-if="
                            reviewStatusInfo.commitType === 1 &&
                            reviewStatusInfo.commitStatus === 2
                        "
                        type="primary"
                        link
                        :loading="withdrawLoading"
                        @click="withdraw"
                    >
                        撤回审核
                    </el-button>
                    <!-- 最新的提交记录为提交审核时，并且状态为【审核成功】才显示发布按钮 -->
                    <el-button
                        v-hasPermi="['enttp:program:release']"
                        v-if="
                            reviewStatusInfo.commitType === 1 &&
                            reviewStatusInfo.commitStatus === 0
                        "
                        type="primary"
                        link
                        :loading="releaseLoading"
                        @click="release"
                    >
                        发布小程序
                    </el-button>
                </div>
            </div>
        </div>
        <!-- 基本信息 -->
        <PubTitle class="mt-30 mb-6" title="基本信息" />
        <div class="info-item">
            <div class="left">小程序名称：</div>
            <div class="right">
                {{ authInfo && authInfo.nick_name }}
            </div>
        </div>
        <div class="info-item">
            <div class="left">小程序头像：</div>
            <div class="right">
                <img
                    v-if="authInfo"
                    :src="authInfo.head_img"
                    class="w-50 h-50"
                />
            </div>
        </div>
        <div class="info-item">
            <div class="left">服务类目：</div>
            <div class="right">{{ authInfo && authInfo.categories }}</div>
        </div>
        <div class="info-item">
            <div class="left">主体信息：</div>
            <div class="right">{{ authInfo && authInfo.principal_name }}</div>
        </div>
        <div class="info-item">
            <div class="left">AppID(小程序ID)：</div>
            <div class="right">{{ authInfo && authInfo.authorizer_appid }}</div>
        </div>
    </div>

    <el-dialog
        v-model="showBackVersion"
        title="可回退版本"
        width="1000"
        top="10vh"
    >
        <BackVersion ref="backVersionRef" @back="init" />
    </el-dialog>

    <el-dialog
        v-model="showUpdateRecord"
        title="更新记录"
        width="1000"
        top="10vh"
    >
        <UpdateRecord ref="updateRecordRef" />
    </el-dialog>

    <el-dialog
        v-model="state.showIframe"
        title="授权"
        width="1200"
        top="5vh"
        destroy-on-close
    >
        <iframe
            ref="iframeRef"
            :src="state.frameUrl"
            height="600"
            class="w-100%"
        ></iframe>
    </el-dialog>
</template>

<script setup>
import cellTip from "@/components/cell-tip.vue";
import PubTitle from "@/components/PubTitle.vue";
import {
    getAuthInfo,
    getVersionInfo,
    getTrialQRCode,
    submitMiniAppReview,
    commitMiniAppCode,
    getReviewStatus as getReviewStatusApi,
    releaseMiniApp,
    getMiniAppAuthorizeStatus,
    authorizeMiniApp,
    withdrawMiniAppReview,
} from "@/apis/system/miniapp.js";
import { inject, onMounted, reactive, toRefs, ref, nextTick } from "vue";
import UpdateRecord from "./UpdateRecord.vue";
import BackVersion from "./BackVersion.vue";
import { useDictStore } from "@stores/dict.js";

const dictStore = useDictStore();
dictStore.getDictMembers("mini_program_commit_type");
dictStore.getDictMembers("mini_program_commit_status");

const $message = inject("$message");

const backVersionRef = ref(null);
const updateRecordRef = ref(null);
const iframeRef = ref(null);

const state = reactive({
    authInfo: null,
    versionInfo: null,
    reviewStatusInfo: {},
    qrCode: null,
    showBackVersion: false,
    showUpdateRecord: false,
    commitLoading: false,
    reviewLoading: false,
    releaseLoading: false,
    withdrawLoading: false,
    isAuthorized: false,
    showIframe: false,
    frameUrl: "",
});

const {
    authInfo,
    versionInfo,
    reviewStatusInfo,
    qrCode,
    showBackVersion,
    showUpdateRecord,
    commitLoading,
    reviewLoading,
    releaseLoading,
    withdrawLoading,
} = toRefs(state);

onMounted(() => {
    init();
});

const init = async () => {
    await getAuthStatus();
    if (!state.isAuthorized) return;
    getAuthData();
    getVersion();
    getReviewStatus();
};

const getAuthStatus = async () => {
    const res = await getMiniAppAuthorizeStatus();
    if (res.data.code === 200) {
        state.isAuthorized = res.data.data;
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

const getAuthData = async () => {
    const res = await getAuthInfo();
    if (res.data.code === 200) {
        const {
            authorization_info: { authorizer_appid },
            authorizer_info: {
                nick_name,
                principal_name,
                head_img,
                MiniProgramInfo: { categories },
            },
        } = res.data.data;
        state.authInfo = {
            authorizer_appid,
            nick_name,
            principal_name,
            head_img,
            categories: categories.length
                ? Object.values(categories[0]).join(" > ")
                : "",
        };
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

const getVersion = async () => {
    const res = await getVersionInfo();
    if (res.data.code === 200) {
        if (res.data.data?.exp_info) {
            let {
                exp_info: { exp_version, exp_desc },
            } = res.data.data;
            const descArr = exp_desc.split("在");
            exp_desc = descArr[descArr.length - 1];
            state.versionInfo = {
                exp_version,
                exp_desc: "于" + exp_desc,
            };
        }
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

const getCode = async () => {
    const res = await getTrialQRCode();
    if (res.data.code === 200) {
        state.qrCode = "data:image/png;base64," + res.data.data;
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

const onClickBackVersion = () => {
    state.showBackVersion = true;
    if (backVersionRef.value) {
        backVersionRef.value.pubParams();
    } else {
        nextTick(() => {
            backVersionRef.value.pubParams();
        });
    }
};

const onClickUpdateRecord = () => {
    state.showUpdateRecord = true;
    if (updateRecordRef.value) {
        updateRecordRef.value.pubParams();
    } else {
        nextTick(() => {
            updateRecordRef.value.pubParams();
        });
    }
};

const commit = async () => {
    state.commitLoading = true;
    const res = await commitMiniAppCode({ entType: 0 });
    if (res.data.code === 200) {
        $message({ message: "提交成功", type: "success" });
        init();
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
    state.commitLoading = false;
};

const review = async () => {
    state.reviewLoading = true;
    const res = await submitMiniAppReview({ entType: 0 });
    if (res.data.code === 200) {
        $message({ message: "提交成功", type: "success" });
        init();
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
    state.reviewLoading = false;
};

const withdraw = async () => {
    state.withdrawLoading = true;
    const res = await withdrawMiniAppReview();
    if (res.data.code === 200) {
        $message({ message: "撤回成功", type: "success" });
        init();
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
    state.withdrawLoading = false;
};

const getReviewStatus = async () => {
    const res = await getReviewStatusApi({ entType: 0 });
    if (res.data.code === 200) {
        state.reviewStatusInfo = res.data.data;
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

const release = async () => {
    state.releaseLoading = true;
    const res = await releaseMiniApp();
    if (res.data.code === 200 && res.data.data) {
        $message({ message: "发布成功", type: "success" });
        init();
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
    state.releaseLoading = false;
};

// 监听来自iframe的消息，授权成功后关闭iframe，获取授权信息
window.addEventListener(
    "message",
    (e) => {
        if (e.origin !== "https://testsystem.huashutong.com") {
            // 验证消息来源
            return;
        }
        if (e.data.isSuccessfulAuthWx) {
            state.showIframe = false;
            init();
        }
    },
    false
);

const openIframe = async () => {
    // 系统后台授权页面
    const authUrl = "https://testsystem.huashutong.com/#/authorize";
    const res = await authorizeMiniApp({
        // 授权成功重定向地址
        callBackUrl: `${authUrl}?success=true&source_domain=${encodeURIComponent(
            window.location.origin
        )}`,
    });
    if (res.data.code === 200) {
        if (!res.data.data) return;
        // url 为微信授权地址
        state.frameUrl = `${authUrl}?url=${encodeURIComponent(res.data.data)}`;
        state.showIframe = true;
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};
</script>

<style scoped lang="less">
.info-item {
    display: flex;
    height: 76px;
    align-items: center;
    .left {
        width: 140px;
        text-align: right;
        font-size: 14px;
        color: rgb(100, 101, 102);
        margin-right: 12px;
    }
    .right {
        display: flex;
        flex-flow: row nowrap;
        justify-content: space-between;
        align-items: center;
        flex: 1;
        border-bottom: 1px solid rgb(235, 237, 240);
        height: 100%;
        padding-top: 4px;
    }
}
</style>
